
#include <glad/glad.h> 
#include <GLFW/glfw3.h>

#include <iostream>
#include <stdio.h>

#include <sys/time.h>
#include <string.h>

#define SCR_WIDTH           (800)
#define SCR_HEIGHT          (600)

void framebuffer_size_callback(GLFWwindow *window, int width, int height);
void processInput(GLFWwindow *window);

int main(int agrc, char *argv[])
{
    int run_cnt = 0;
    char app_name[] = "app1_window build time:";
    char win_name[256] = "";
#ifdef DEBUG_glfwWindowShouldClose
    struct timeval start, end, current;
#endif
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    sprintf(win_name, "%s %s-%s", app_name, __DATE__, __TIME__);
    std::cout << win_name << std::endl;
    GLFWwindow *window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, win_name, NULL, NULL);
    if(NULL == window)
    {
        std::cout << "Failed to create GLFW window!" << std::endl;
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

    if(!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        std::cout << "Failed to initlialize GLAD!" << std::endl;
        glfwTerminate();
        return -1; 
    }
#ifdef DEBUG_glfwWindowShouldClose
    memset(&start, 0, sizeof(start));
    memset(&end, 0, sizeof(end));
    memset(&current, 0, sizeof(current));
#endif
    while(!glfwWindowShouldClose(window))
    {
        processInput(window);

        glfwSwapBuffers(window);
        glfwPollEvents();
#ifdef DEBUG_glfwWindowShouldClose
        gettimeofday(&current, NULL);
        start.tv_sec    = end.tv_sec;
        start.tv_usec   = end.tv_usec;
        end.tv_sec    = current.tv_sec;
        end.tv_usec   = current.tv_usec;
        if((0 == start.tv_sec) && (0 == start.tv_usec))
        {
            start.tv_sec    = current.tv_sec;
            start.tv_usec   = current.tv_usec;
        }
        std::cout << "run cnt=" << run_cnt++ << "   cost_time=" << (end.tv_sec - start.tv_sec) * 1000 + (end.tv_usec - start.tv_usec) / 1000 << std::endl;
#endif
    }
    glfwTerminate();
    return 0;
}

void framebuffer_size_callback(GLFWwindow *window, int width, int height)
{
    glViewport(0, 0, width, height);
}

void processInput(GLFWwindow *window)
{
    if(GLFW_PRESS == glfwGetKey(window, GLFW_KEY_ESCAPE))
    {
        glfwSetWindowShouldClose(window, true);
    }
}
